/**********************************************************************************
 * Copyright (c) 2012 - 2012,  quick_tools, All right reserved
 * Title: com.adc.quicktools  StringUtil.java 
 * @author shen  shenqiao2012@163.com 
 *  2012-6-19 下午8:33:53 
 *********************************************************************************/


package com.adc.quicktools;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Date;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import com.adc.quicktools.constants.ConstantDefine;




public class StringUtil {
	
	/**
	 * 
	 * Description:   检查string的值是否非空
	 * author:  shen
	 * @param string  
	 * @return boolean  空则返回false，反之true
	 */
	public static boolean checkStringValue(String string) {
		if (string!=null && !"".equals(string)) {
			return true;
		}else {
			return false;
		}
	}
	
	/**
	 * 
	 * Description: 将字符串中连续的同一符号压缩为一个
	 * author:  shen
	 * @param target
	 * @param sameSymbol
	 * @return String
	 */
	public static String compressionSameSymbol(String target,char sameSymbol) {
		String returnValue = "";
		int size = target.length();
		char[] targets = new char[size];
		targets = target.toCharArray();
		char pre = 0;
		for (int i = 0; i < targets.length; i++) {
			if (targets[i] == sameSymbol) {
				if (pre != sameSymbol) {
					returnValue = returnValue + targets[i];
					// System.out.println(returnValue);
				}
				pre = targets[i];
			} else {
				pre = targets[i];
				returnValue = returnValue + targets[i];
				// System.out.println(returnValue);
			}
		}
		if (returnValue.length() == 3 && returnValue.contains(".")) {
			returnValue = "*.*";
		}
		if (returnValue.length() < 3 && returnValue.length()>0 && !returnValue.contains(".")) {
			returnValue =""+sameSymbol;
		}

		return returnValue;
	}
	
	
	/**
	 *  将字符串中重复的“*”号去掉，
	 * @param target   目标字符串，例如“****45*{yy}.**G”
	 * @Return String   去重复“*”号的字符串，例如：“*45*{yy}.*G”
	 */
	public static String compressionAsterisk(String target) {
		return compressionSameSymbol(target, '*');
	}
	
	/**
	 *  将字符串中重复的“?”号去掉，
	 * @param target   目标字符串，例如“????45?{yy}.??G”
	 * @Return String   去重复“*”号的字符串，例如：“?45?{yy}.?G”
	 */
	public static String compressionQuestionMask(String target) {
		return compressionSameSymbol(target, '?');
	}
	
	/**
	 * 
	 * Description: 获取target中？的个数序列；
	 * author:  shen
	 * @param target
	 * @return int[]
	 */
	public static int[] countMultiQuestionMask(String target) {
		StringBuffer sBuffer=new StringBuffer();
		Deque<Character> deque=new ArrayDeque<Character>();
		List<String> tempList=new ArrayList<String>();
		char[] cs=target.toCharArray();
		for (int i = 0; i < cs.length; i++) {
			if (cs[i]=='?') {
				deque.add(cs[i]);
			}else {
				if (deque.size() > 0) {
					while (deque.size() > 0) {
						sBuffer.append(deque.pollFirst());
					}
					tempList.add(sBuffer.toString());
					sBuffer = new StringBuffer();
				}
			}
			if (i==cs.length-1&&deque.size()>0) {
				while (deque.size()>0) {
					sBuffer.append(deque.pollFirst());
				}
				tempList.add(sBuffer.toString());
			}
		}
		int[] results=new int[tempList.size()];
		for (int i = 0; i < tempList.size(); i++) {
			results[i]=tempList.get(i).length();
		}
		return results;
	}
	
	/**
	 * 
	 * Description: 根据字符数组中包含的字符，将目标字符串拆分成为数组； 
	 * author:  shen
	 * @param targetString
	 * @param splitChars
	 * @return String[]
	 */
	public static String[] splitByChars(String targetString,Character[] splitChars) {
		Deque<Character> deque=new ArrayDeque<Character>();
		String[] result=null;
		List<String> tempList=new ArrayList<String>();
		char[] target=targetString.toCharArray();
		StringBuffer sBuffer=new StringBuffer();
		for (int i = 0; i < target.length; i++) {
			char temp=target[i];
			deque.add(temp);
			if (ObjectUtil.arrayToString(splitChars, "").contains(temp+"")) {
				deque.pollLast();
				if (deque.size()>0) {
					while (deque.size()>0) {
						sBuffer.append(deque.pollFirst());
					}
				}else {
					sBuffer.append("");
				}
//				System.out.println(sBuffer.toString());
				tempList.add(sBuffer.toString());
				sBuffer=new StringBuffer();
			}
			if (i==(target.length-1)&&deque.size()>0) {
				while (deque.size()>0) {
					sBuffer.append(deque.pollFirst());
				}
				tempList.add(sBuffer.toString());
			}
		}
		result=new String[tempList.size()];
		for (int i = 0; i < tempList.size(); i++) {
			result[i]=tempList.get(i);
		}
		return result;
	}
	
	
	/**
	 * 
	 * Description: 从配置文件中返回指定key的value；快捷使用时，可用；
	 * author:  shen
	 * @deprecated
	 * @param key  
	 * @param filename 指定的资源文件名，资源文件根目录为resource下；该参数可为空，为空时，默认获取config.properties文件
	 * @return String
	 */
	@Deprecated
	public static String getValuesFromProperties(String key,String filename) {
		Properties properties=new Properties();
		String outvalue=null;
		try {
			if (!checkStringValue(filename)) {
				properties = PropertiesUtil.loadProperties(ConstantDefine.RESOURCE_ROOT + ConstantDefine.RESOURCE_DefaultFile);
			}else {
				properties = PropertiesUtil.loadProperties(ConstantDefine.RESOURCE_ROOT + filename);
			}
			outvalue=properties.getProperty(key);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally{
			properties=null;
			System.gc();   //  将临时使用的内存对象清空
		}
		return outvalue;
	}
	
	/**
	 * 
	 * Description:   给指定内容添加上指定类型的括号
	 * author:  shen
	 * @param bracketType  指定的括号类型
	 * @param content   指定的内容
	 * @return String
	 */
	public static String addBrackets(String bracketType,String content) {
		String outString="";
		if (checkStringValue(bracketType)&&checkStringValue(content) && ( ConstantDefine.Bracket_Round.equals(bracketType) ||
				ConstantDefine.Bracket_Square.equals(bracketType)|| ConstantDefine.Bracket_Curly.equals(bracketType) ) ) {
			char[] bracketArray=bracketType.toCharArray();
			if (bracketArray.length==2) {
				outString=bracketArray[0]+content+bracketArray[1];
				System.out.println(" 添加完成的内容为： "+outString);
			}
		}
		return outString;
	}

	/**
	 * 
	 * Description:   根据传入的目标字符串，取出括号内的内容，包括“()”、“[]”、“{}”
	 * author:  shen
	 * @param target  目标字符串
	 * @param bracketType  括号类型
	 * @return String  括号内的内容
	 */
	public static String pickFromBrackets(String target,String bracketType) {
		String outString="";
		if (checkStringValue(bracketType) && ( ConstantDefine.Bracket_Round.equals(bracketType) ||
				ConstantDefine.Bracket_Square.equals(bracketType)|| ConstantDefine.Bracket_Curly.equals(bracketType) )) {
			char[] bracketArray=bracketType.toCharArray();
			if (bracketArray.length==2) {
				outString=target.substring(target.indexOf(bracketArray[0])+1, target.indexOf(bracketArray[1]));
				System.out.println(" 取出 "+target+ " 中的内容为： "+outString);
			}
		}else {
			outString = null;
		}
		return outString;
	}
	
	/**
	 * 
	 * Description:   根据format1 将timestring转化成符合format2的timeString
	 * author:  shen
	 * @param timeString  待转换的时间串
	 * @param format1  符合时间格式的字符串1
	 * @param format2  符合时间格式的字符串1
	 * @return String
	 */
	public static String timeFormatExchange(String timeString ,String format1,String format2) {
		String outValue=null;
		SimpleDateFormat simple;
		try {
			if (checkStringValue(timeString)&&checkStringValue(format1) && checkStringValue(format2)) {
				simple=new SimpleDateFormat(format1);
				Date date=simple.parse(timeString);
				simple=new SimpleDateFormat(format2);
				outValue=simple.format(date);
				System.out.println("Exchange time from fomart1["+format1+"] to formart2["+format2+"],and result:"+outValue);
			}
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return outValue;
	}
	
	/**
	 * 
	 * Description:  检查文件名中是否包含敏感字符
	 * author:  shen
	 * @param fileName  传入的文件名
	 * @return boolean
	 */
	public static boolean checkFileName(String fileName) {
		boolean result=false;
		String[] strArray=ConstantDefine.FILE_ERROR_LETTER;
		if (checkStringValue(fileName)) {
			for (String string : strArray) {
				if (fileName.contains(string)) {
					result=false;
					break;
				}else {
					result=true;
				}
			}
		}
		return result;
	}
	
	/**
	 * 
	 * Description: 将String 数组的内容用逗号分隔拼接字符串并返回；
	 * author:  shen
	 * @param strArray  string的数组
	 * @return String
	 */
	public static String arrayToString(String[] strArray) {
		String result="";
		if (strArray.length>0) {
			for (String s : strArray) {
				result=result.concat(","+s);
			}
			result=result.substring(1);
		}
		return result;
	}
	
	/**
	 * 
	 * Description: 根据传入的String型的path，截取其parentPath，好处是将路径分隔符均换成“/”
	 * author:  shen
	 * @param path
	 * @return String
	 */
	public static String getParentByString(String path) {
		String result="";
		if (checkStringValue(path)) {
			String temp=path.replace("\\", "/");
			if (temp.endsWith("/")) {
				temp=temp.substring(0,temp.lastIndexOf("/"));
			}
			if (temp.split("/").length>1) {
				result=temp.substring(0,temp.lastIndexOf("/")+1);
			}else {
				result="/";
			}
		}
		return result;
	}
	
	/**
	 * 
	 * Description: 根据传入的String型的path，截取其name，好处是保留文件名中所带有的符号，如通配符；
	 * author:  shen
	 * @param path
	 * @return String
	 */
	public static String getNameByString(String path) {
		String result="";
		if (checkStringValue(path)) {
			String temp=path.replace("\\", "/");
			if (temp.endsWith("/")) {
				temp=temp.substring(0,temp.lastIndexOf("/"));
				
			}
			if (temp.split("/").length>1) {
				result=temp.substring(temp.lastIndexOf("/")+1);
			}else {
				result="/";
			}
		}
		return result;
	}
	
	/**
	 * 
	 * Description: 首字母小写
	 * author:  shen
	 * @param string 
	 * @return String
	 */
	public static String lowerFirst(String string) {
		return string.substring(0, 1).toLowerCase()+string.substring(1);
	}
	
	/**
	 * 
	 * Description: 首字母大写
	 * author:  shen
	 * @param string  
	 * @return String
	 */
	public static String upperFirst(String string) {
		return string.substring(0, 1).toUpperCase()+string.substring(1);
	}
	
	/**
	 * 
	 * Description: 将一个基于string的list按照string长度从小到大排列后，并返回；
	 * author:  shen
	 * @param list
	 * @return List<String>
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static List<String> sortByLength(List<String> list) {
		Map<Integer,Integer> newMap= new HashMap<Integer,Integer>();
		for (int i = 0; i < list.size(); i++) {
			newMap.put(i, list.get(i).length());
		}
		List<Integer> valuelist=new ArrayList<Integer>(newMap.values());
		valuelist=ListUtil.autoNatureSort(valuelist);
		List<String> tempList=new ArrayList<String>();
		for (Integer intVal : valuelist) {
			for (Iterator i = newMap.entrySet().iterator(); i.hasNext();) {
				Entry<Integer, Integer> entry =(Entry<Integer, Integer>) i.next();
				if (intVal==entry.getValue()) {
					tempList.add(list.get(entry.getKey()));
					break;
				}
			}
		}
		System.out.println("List size["+list.size()+"];new List size["+tempList.size()+"]");
		return tempList;
	}
	
	/**
	 * 
	 * Description: 根据位置索引，将目标字符串指定位置的连续字符替换成为指定的替换字符；
	 * author:  shen
	 * @param target 目标字符串
	 * @param match 替换字符串
	 * @param start 起始索引
	 * @param end 结束索引
	 * @return String 
	 */
	public static String replaceByIndex(String target,String match,int start,int end) {
		String result=null;
		if (checkStringValue(target)&&checkStringValue(match)&&start<end&&end<target.length()) {
			result=target.replace(target.substring(start, end), match);
		}else {
			throw new ArrayIndexOutOfBoundsException(
					"Parameter is Error![target:"+target+",match:"+match
					+",start:"+start+",end:"+end+"]");
		}
		System.out.println("Change["+target+"] to["+result+"].");
		return result;
	}
}
